﻿using lumo;
using lumo.display.animation2D;
using lumo.display.object2D;
using lumo.scene;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;

namespace game.scene
{
    /// <summary>
    /// This scene shows logos and brands before the title scene
    /// </summary>
    public class SceneIntro : IScene
    {

        #region Configurable Variables

        /// <summary>
        /// Frames to wait before fading in
        /// </summary>
        protected const float PRE_WAIT = 0;
        /// <summary>
        /// Time to fade in
        /// </summary>
        protected const float FADE_IN = 1000.0f;
        /// <summary>
        /// Frame to wait while the texture is being shown
        /// </summary>
        protected const float MID_WAIT = 1000.0f;
        /// <summary>
        /// Time to fade out
        /// </summary>
        protected const float FADE_OUT = 1000.0f;
        /// <summary>
        /// Frames to wait after fading out
        /// </summary>
        protected const float POS_WAIT = 0;
        /// <summary>
        /// Texture names list
        /// </summary>
        protected string[] _TextureNames = new string[] { "Graphics/Pictures/Lumo Engine" };

        #endregion

        #region Instance Variables

        /// <summary>
        /// Texture index (from the list above)
        /// </summary>
        protected int _TextureIndex = -1;
        /// <summary>
        /// Sprite
        /// </summary>
        protected Sprite _BackgroundSprite;
        /// <summary>
        /// Animator
        /// </summary>
        protected SerialAnimation2D _FadeAnimation;

        #endregion

        #region IScene

        /// <summary>
        /// Creates the scene objects
        /// </summary>
        /// <param name="component">LumoComponent instance</param>
        public void Start(LumoComponent component)
        {
            Song song = component.Content.Load<Song>("Audio/BGM/Title");
            MediaPlayer.Play(song);
            // If there is no image to show
            if ((_TextureNames == null) || (_TextureNames.Length == 0))
            {
                // Jumps to title scene
                component.Scene = new SceneTitle(this);
                // Avoids the rest of the code
                return;
            }
            // Creates the sprite what will handle the texture
            _BackgroundSprite = new Sprite();
            // Sets the global box overlay color to black (in order to make the fade effect)
            Global.Box.Color = new Color(0.0f, 0.0f, 0.0f, 1.0f);
            // Starts a serial animation
            _FadeAnimation = new SerialAnimation2D();
                // Adds a frame wait action to the queue
                _FadeAnimation.Add(new WaitAnimation2D(PRE_WAIT));
                // Adds a fade in animation to the queue
                _FadeAnimation.Add(new ColorAnimation2D(new Color(0.0f, 0.0f, 0.0f, 0.0f), FADE_IN, Smooth.Arrival, Loop.None, Global.Box));
                // Adds another frame wait action to the queue
                _FadeAnimation.Add(new WaitAnimation2D(MID_WAIT));
                // Adds a fade out animation to the queue
                _FadeAnimation.Add(new ColorAnimation2D(new Color(0.0f, 0.0f, 0.0f, 1.0f), FADE_OUT, Smooth.Start, Loop.None, Global.Box));
                // Adds another frame wait action to the queue
                _FadeAnimation.Add(new WaitAnimation2D(POS_WAIT));
        }

        /// <summary>
        /// Updates the scene objects
        /// </summary>
        /// <param name="component">LumoComponent instance</param>
        public void Update(LumoComponent component)
        {
            // Otherwise, checks if the serial animation has finished
            if (_FadeAnimation.Finished)
                // If so, goes to the next texture and repeat the animation
                NextTexture(component);
            // Updates the animaton
            _FadeAnimation.Update(component);
        }

        /// <summary>
        /// Draws the scene objects
        /// </summary>
        /// <param name="component">LumoComponent instance</param>
        public void Draw(LumoComponent component)
        {
            // Clears everything drawn previously
            component.GraphicsDevice.Clear(Color.Black);
            // Starts drawing 2D objects
            component.SpriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, null, Global.ScreenMatrix);
                // Draws the main sprite
                _BackgroundSprite.Draw(component.SpriteBatch);
                // Draws the global box overlay
                Global.Box.Draw(component.SpriteBatch);
            // Ends drawing 2D objects
            component.SpriteBatch.End();
        }

        /// <summary>
        /// Destroys the scene objects
        /// </summary>
        /// <param name="component">LumoComponent instance</param>
        public void Terminate(LumoComponent component) {}

        #endregion

        /// <summary>
        /// Goes to the next texture. If there isn't any left, jumps to title
        /// </summary>
        /// <param name="component">LumoComponent instance</param>
        protected void NextTexture(LumoComponent component)
        {
            // Updates the texture index
            _TextureIndex++;
            // If the last texture was the last one of the list
            if (_TextureIndex == _TextureNames.Length)
                // Jumps to title scene
                component.Scene = new SceneTitle(this);
            // Otherwise
            else
            {
                // Loads the new texture by its name in the list and sets it to the sprite
                _BackgroundSprite.Texture = component.Game.Content.Load<Texture2D>(_TextureNames[_TextureIndex]);
                // Adjusts the sprite horizontal center point to the its middle
                _BackgroundSprite.OX = _BackgroundSprite.Texture.Width / 2;
                // Adjusts the sprite vertical center point to the its middle
                _BackgroundSprite.OY = _BackgroundSprite.Texture.Height / 2;
                // Moves the sprite to the horizontal center of the screen
                _BackgroundSprite.X = Global.DefaultScreenSize.X / 2;
                // Moves the sprite to the vertical center of the screen
                _BackgroundSprite.Y = Global.DefaultScreenSize.Y / 2;
                // Repeats the fade animation
                _FadeAnimation.Reset();
            }
        }

    }

}